/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * TrainingBook
 * Copyright (C) Arnaud Duval 2010 <arnaud.duval@gmail.com>
 * 
 * Projects is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Projects is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "activity-edit-dialog.hpp"
#include "track-elevation-dialog.hpp"
#include <DateSelectionDialog.hpp>

///@brief Default constructor
///@param titre Title of the dialog
///@param parent Pointer to the parent window
///@param actTypes list of activity types
ActivityEditDialog::ActivityEditDialog(std::string titre, 
                                       Gtk::Window *parent,
                                       ActivityTypes actTypes)
                    : Gtk::Dialog(titre, *parent)
{
    ///@brief Set the border width of the window
    set_border_width(0);
    ///@brief set the labels text
    FillLabels();

    ///@brief Additions of the different types of activities
    for(unsigned int i = 0 ; i < actTypes.NbTypes() ; i++)
        typeActCBT.append_text(actTypes.Type(i));

    ///@brief Additions of the differents type of quality to be trained
    ///@todo Faire une classe pour les différents types de qualité
    qualityCBT.append_text("Rythme");
    qualityCBT.append_text("Endurance fondamentale");
    qualityCBT.append_text("Force sous maximale");
    qualityCBT.append_text("Seuil");
    qualityCBT.append_text("Déblocage");
    qualityCBT.append_text("Toutes");


    ///@brief Configuration of the button to load a GPX file
    gpxButton.set_label("...");
    gpxButton.signal_clicked().connect(sigc::mem_fun(*this,
                                                     &ActivityEditDialog::on_button_load_gpx_clicked));

    ///@brief Configuration of the button for plotting the GPS track ascent
    plotGpxButton.set_label("Dénivelé");
    plotGpxButton.signal_clicked().connect(sigc::mem_fun(*this,
                                                         &ActivityEditDialog::on_button_plot_gpx_clicked));

    ///@brief Configuration of the button to autocompute the consumed caloriesLabel
    caloriesButton.set_label("auto");
    caloriesButton.signal_clicked().connect(sigc::mem_fun(*this,
                                                          &ActivityEditDialog::on_button_compute_calories_clicked));

    ///@brief Configuration of the button to select the date
    dateButton.set_label("...");
    dateButton.signal_clicked().connect(sigc::mem_fun(*this,
                                                      &ActivityEditDialog::on_button_select_date_clicked));

    ///@brief Settings the parameters for the entry of date and time
    dateEntry.SetPrintFormat("dd/mm/yyyy");
    timeEntry.SetPrintFormat("hh:nn");

    ///@brief Setting the commments text view and its buffer
    commentsTextBuffer = Gtk::TextBuffer::create();
    commentsTextView.set_buffer(commentsTextBuffer);

    ///@brief Setting the button to unembed the GPS track
    unembedTrackButton.set_label("Désencapsuler la trace");
    unembedTrackButton.signal_clicked().connect(sigc::mem_fun(*this,
                                                &ActivityEditDialog::on_button_unembed_track_clicked));
    
    testButton.set_label("test");
    testButton.signal_clicked().connect(sigc::mem_fun(*this,
                                        &ActivityEditDialog::on_button_test_clicked));

    
    


    dateHBox.pack_start(dateLabel, Gtk::PACK_EXPAND_WIDGET);
    dateHBox.pack_start(dateEntry, Gtk::PACK_SHRINK);
    dateHBox.pack_start(dateButton, Gtk::PACK_SHRINK);

    timeHBox.pack_start(timeLabel, Gtk::PACK_EXPAND_WIDGET);
    timeHBox.pack_start(timeEntry, Gtk::PACK_SHRINK);
    
    locationHBox.pack_start(locationLabel, Gtk::PACK_EXPAND_WIDGET);
    locationHBox.pack_start(locationEntry, Gtk::PACK_SHRINK);
    
    typeActHBox.pack_start(typeActLabel, Gtk::PACK_EXPAND_WIDGET);
    typeActHBox.pack_start(typeActCBT, Gtk::PACK_SHRINK);
    
    distanceHBox.pack_start(distanceLabel, Gtk::PACK_EXPAND_WIDGET);
    distanceHBox.pack_start(distanceEntry, Gtk::PACK_SHRINK);
    
    durationHBox.pack_start(durationLabel, Gtk::PACK_EXPAND_WIDGET);
    durationHBox.pack_start(durationEntry, Gtk::PACK_SHRINK);
    
    fcMoyHBox.pack_start(fcMoyLabel, Gtk::PACK_EXPAND_WIDGET);
    fcMoyHBox.pack_start(fcMoyEntry, Gtk::PACK_SHRINK);

    fcMaxHBox.pack_start(fcMaxLabel, Gtk::PACK_EXPAND_WIDGET);
    fcMaxHBox.pack_start(fcMaxEntry, Gtk::PACK_SHRINK);

    gpxHBox.pack_start(gpxLabel, Gtk::PACK_EXPAND_WIDGET);
    gpxHBox.pack_start(gpxButton, Gtk::PACK_SHRINK);

    caloriesHBox.pack_start(caloriesLabel, Gtk::PACK_EXPAND_WIDGET);
    caloriesHBox.pack_start(caloriesEntry, Gtk::PACK_SHRINK);
    caloriesHBox.pack_start(caloriesButton, Gtk::PACK_SHRINK);

    qualityHBox.pack_start(qualityLabel, Gtk::PACK_EXPAND_WIDGET);
    qualityHBox.pack_start(qualityCBT, Gtk::PACK_SHRINK);

    commentsVBox.pack_start(commentsLabel, Gtk::PACK_EXPAND_WIDGET);
    commentsVBox.pack_start(commentsTextView, Gtk::PACK_SHRINK);
    
    plotGpxHBox.pack_start(plotGpxButton, Gtk::PACK_SHRINK);

    for(unsigned int i = 0 ; i< 7 ; i++)
    {
        intensityEntries[i].set_width_chars(3);
        intensityVBoxes[i].pack_start(intensityLabels[i],Gtk::PACK_SHRINK);
        intensityVBoxes[i].pack_start(intensityEntries[i],Gtk::PACK_SHRINK);
        intensitiesHBox.pack_start(intensityVBoxes[i]);
    }

    unembedTrackHBox.pack_start(unembedTrackButton, Gtk::PACK_SHRINK);

    get_vbox()->pack_start(dateHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(timeHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(locationHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(typeActHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(distanceHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(durationHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(fcMoyHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(fcMaxHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(gpxHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(qualityHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(intensitiesHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(caloriesHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(commentsVBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(plotGpxHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(unembedTrackHBox, Gtk::PACK_SHRINK);
    get_vbox()->pack_start(testButton, Gtk::PACK_SHRINK);
    
    ///@brief Addition of buttons for cancel or validation
    add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
    add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
    
    show_all();
}

///@brief Destructor
ActivityEditDialog::~ActivityEditDialog()
{

}

///@brief Set the current activity
///@param a Activity to become the current activity
void ActivityEditDialog::SetActivity(ActivityHeader a)
{
    activity = a;
    Update();
}

///@brief Return the current activity
ActivityHeader ActivityEditDialog::GetActivity()
{
    return activity;
}

void ActivityEditDialog::on_button_load_gpx_clicked()
{
    Gtk::FileChooserDialog dialog("Ouvrir...",
                                  Gtk::FILE_CHOOSER_ACTION_OPEN);
    dialog.set_transient_for(*this);
    
    //Add button to the dialog
    dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
    dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);

    //Set initial directory
    dialog.set_current_folder(Glib::get_home_dir());
    
    //Add filters
    Gtk::FileFilter filter_gpx;
    filter_gpx.set_name("Fichier GPX");
    filter_gpx.add_pattern("*.gpx");
    dialog.add_filter(filter_gpx);
    
    //Show the dialog
    int result = dialog.run();
    switch(result)
    {
        case(Gtk::RESPONSE_OK):
        {
            std::cout << "The function to load a GPX track should be coded\n";
            //activity.LoadGPX(dialog.get_filename());
            Update();
            break;
        }
        case(Gtk::RESPONSE_CANCEL):
        {
            break;
        }
        default:
        {
            break;
        }
    }
}

void ActivityEditDialog::on_button_plot_gpx_clicked()
{
    ///@warning This function should be rewritten
    /*if(activity.GetTrackIsEmbedded())
    {
        TrackElevationDialog dialog(this, activity.GetTrack());
        dialog.run();
    }
    else
    {
        Track trace;
        if (trace.ReadGPX(gpsTrackDirectory + "/" + activity.GetTrackFile()))
        {
            TrackElevationDialog dialog(this, trace);
            dialog.run();
        }
    }*/
}

///@brief Action for computing consuled calories
void ActivityEditDialog::on_button_compute_calories_clicked()
{
    std::cout << "Click sur le bouton pour calculer les calories\n";
    ///@todo Implémenter le calcul automatique des calories consommées
}

///@brief Action when clicking on the date selection button
void ActivityEditDialog::on_button_select_date_clicked()
{
    DateSelectionDialog dialog(this);
    dialog.SetDate(activity.GetDateTime());

    int result = dialog.run();
    switch(result)
    {
        case(Gtk::RESPONSE_OK):
        {
            DateTime activityDate = activity.GetDateTime();
            DateTime selectedDate = dialog.GetDate();
            activityDate.SetYear(selectedDate.GetYear());
            activityDate.SetMonth(selectedDate.GetMonth());
            activityDate.SetDay(selectedDate.GetDay());
            activity.SetDateTime(activityDate);
            Update();
            break;
        }
        case(Gtk::RESPONSE_CANCEL):
        {
            break;
        }
        default:
        {
            break;
        }
    }
}

///@brief Action when clicking on the button to unembed the GPS track
void ActivityEditDialog::on_button_unembed_track_clicked()
{
    ///@warning This function should be removed
    //activity.UnembedTrack(gpsTrackDirectory);
}

///@brief Action when clicking on test button
void ActivityEditDialog::on_button_test_clicked()
{
    std::cout << "Click sur le bouton test\n";
    //DateSelectionDialog dialog(this);
    //dialog.run();
}

///@brief Update the content of dialog with activity values
void ActivityEditDialog::Update()
{
    distanceEntry.SetValue(activity.GetDistance());
    durationEntry.SetValue(activity.GetDuration());
    dateEntry.SetValue(activity.GetDateTime());
    timeEntry.SetValue(activity.GetDateTime());
    fcMoyEntry.SetValue(activity.GetFCMoy());
    fcMaxEntry.SetValue(activity.GetFCMax());
    locationEntry.set_text(activity.GetLocation());
    typeActCBT.set_active_text(activity.GetActivityType());
    commentsTextBuffer->set_text(activity.GetComments());
    qualityCBT.set_active_text(activity.GetQuality());
    caloriesEntry.SetValue(activity.GetCalories());
}

///@brief Update the activity values with the content of the dialog
void ActivityEditDialog::UpdateActivity()
{
    activity.SetActivityType(typeActCBT.get_active_text());
    DateTime date(dateEntry.GetValue().GetYear(),
                  dateEntry.GetValue().GetMonth(),
                  dateEntry.GetValue().GetDay(),
                  timeEntry.GetValue().GetHour(),
                  timeEntry.GetValue().GetMinute(),
                  timeEntry.GetValue().GetSecond());
    activity.SetDateTime(date);
    activity.SetDistance(distanceEntry.GetValue());
    activity.SetDuration(durationEntry.GetValue());
    activity.SetFCMoy(fcMoyEntry.GetValue());
    activity.SetFCMax(fcMaxEntry.GetValue());
    activity.SetLocation(locationEntry.get_text());
    activity.SetComments(commentsTextBuffer->get_text());
    activity.SetCalories(caloriesEntry.GetValue());
    activity.SetQuality(qualityCBT.get_active_text());
}

///@brief Set the initial displayed date
///@param Ddate Date value to be displayed
void ActivityEditDialog::SetDate(DateTime Ddate)
{
    activity.SetDateTime(Ddate);
    Update();
}

///@brief Called at validation
///@param response_id Response ID
void ActivityEditDialog::on_response(int response_id)
{
    if(response_id == Gtk::RESPONSE_OK)
        UpdateActivity();
}

///@brief Fill the text labels
void ActivityEditDialog::FillLabels()
{
    dateLabel.set_text("Date :");
    timeLabel.set_text("Heure :");
    locationLabel.set_text("Lieu :");
    distanceLabel.set_text("Distance :");
    typeActLabel.set_text("Type d'activité :");
    durationLabel.set_text("Durée :");
    fcMoyLabel.set_text("FC moy :");
    fcMaxLabel.set_text("FC max :");
    gpxLabel.set_text("Charger une trace GPS :");
    commentsLabel.set_text("Commentaires :");
    caloriesLabel.set_text("Calories :");
    qualityLabel.set_text("Qualité développée :");
    intensityLabels[0].set_text("I1");
    intensityLabels[1].set_text("I2");
    intensityLabels[2].set_text("I3");
    intensityLabels[3].set_text("I4");
    intensityLabels[4].set_text("I5");
    intensityLabels[5].set_text("I6");
    intensityLabels[6].set_text("I7");
}